package HuaRongDao;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GamePanel extends JPanel implements ActionListener,MouseListener,KeyListener{
    int leftX=50,leftY=50;
    int level,W=100;
    int step = 0;//存储当前步数
    int record;//存储当前关卡记录
    Icon[] icons;
    Image[] pics;
    Node[] map;
    Person[] persons;
    Point p1 = new Point(0,0);//鼠标按下时点击的像素坐标
    Point p2 = new Point(0,0);//鼠标释放时点击的像素坐标
    Rectangle leftBoundary = new Rectangle(leftX-10, leftY, 10, 5*W);
    Rectangle rightBoundary = new Rectangle(leftX+4*W, leftY, 10, 5*W);
    Rectangle upBoundary = new Rectangle(leftX, leftY-10, 4*W, 10);
    Rectangle downBoundary = new Rectangle(leftX, leftY+5*W, 4*W, 10);

    public static final int UP=1,DOWN=2,LEFT=3,RIGHT=4;

    MapUtil mapUtil = new MapUtil();

    public GamePanel(int level){
        this.level = level;
        map	= mapUtil.getMap(level);
        persons = new Person[10];
        icons = new Icon[15];
        pics = new Image[15];
        setLayout(null);
        setSize(400, 500);
        getIcons();
        initialize();
        HelpPanel.restart.addMouseListener(new MouseAdapter(){
            public void mouseClicked(MouseEvent e){
                step = 0;
                for(int i=0;i<10;i++){
                    GameClient.gamePanel.remove(persons[i]);
                }
                repaint();
                map = mapUtil.getMap(level);
                GameClient.panel.remove(GameClient.helpPanel);
                GameClient.helpPanel = new HelpPanel(level);
                GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
                GameClient.helpPanel.validate();
                GameClient.gamePanel.validate();
                GameClient.panel.validate();
                initialize();
                setVisible(true);
                GameClient.gamePanel.requestFocus();
                repaint();
            }
        });
    }


    public void paint(Graphics g){
        setLayout(null);
        g.clearRect(0, 0, getWidth(), getHeight());
        for(int i=0;i<10;i++){
            persons[i].requestFocus();
            persons[i].paintComponents(g);
        }
    }


    //获取图片
    private void getIcons() {
        for(int i=0;i<15;i++){
            if(i==0){
                //自适应
                pics[i] = new ImageIcon("images/HuaRongDao/pic"+i+".png").getImage().getScaledInstance(2*W, 2*W,Image.SCALE_SMOOTH);
            }else if(i==1||i==2||i==3||i==4||i==5){
                pics[i] = new ImageIcon("images/HuaRongDao/pic"+i+".png").getImage().getScaledInstance(2*W, W,Image.SCALE_SMOOTH);
            }else if(i==6||i==7||i==8||i==9){
                pics[i] = new ImageIcon("images/HuaRongDao/pic"+i+".png").getImage().getScaledInstance(W, W,Image.SCALE_SMOOTH);
            }else{
                pics[i] = new ImageIcon("images/HuaRongDao/pic"+i+".png").getImage().getScaledInstance(W,2*W,Image.SCALE_SMOOTH);
            }
            icons[i] = new ImageIcon(pics[i]);
        }
        repaint();
    }



    //对游戏布局进行初始化
    private void initialize() {

        for(int i=0;i<10;i++){
            switch(map[i].getId()){
                case 0://曹操，占四格
                    persons[i] = new Person(0,"曹操");
                    persons[i].setIcon(icons[0]);
                    persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, 2*W);
                    break;
                case 1://赵云，占两格
                    persons[i] = new Person(1,"赵云");
                    if(map[i].getDirection()){//横放
                        persons[i].setIcon(icons[1]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, W);
                    }else{//竖放
                        persons[i].setIcon(icons[10]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, 2*W);
                    }
                    break;
                case 2://张飞，占两格
                    persons[i] = new Person(2,"张飞");
                    if(map[i].getDirection()){//横放
                        persons[i].setIcon(icons[2]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, W);
                    }else{//竖放
                        persons[i].setIcon(icons[11]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, 2*W);
                    }
                    break;
                case 3://关羽，占两格
                    persons[i] = new Person(3,"关羽");
                    if(map[i].getDirection()){//横放
                        persons[i].setIcon(icons[3]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, W);
                    }else{//竖放
                        persons[i].setIcon(icons[12]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, 2*W);
                    }
                    break;
                case 4://马超，占两格
                    persons[i] = new Person(4,"马超");
                    if(map[i].getDirection()){//横放
                        persons[i].setIcon(icons[4]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, W);
                    }else{//竖放
                        persons[i].setIcon(icons[13]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, 2*W);
                    }
                    break;
                case 5://黄忠，占两格
                    persons[i] = new Person(5,"黄忠");
                    if(map[i].getDirection()){//横放
                        persons[i].setIcon(icons[5]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, 2*W, W);
                    }else{//竖放
                        persons[i].setIcon(icons[14]);
                        persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, 2*W);
                    }
                    break;
                case 6://小兵，占一格
                    persons[i] = new Person(6,"小兵");
                    persons[i].setIcon(icons[6]);
                    persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, W);
                    break;
                case 7://小兵，占一格
                    persons[i] = new Person(7,"小兵");
                    persons[i].setIcon(icons[7]);
                    persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, W);
                    break;
                case 8://小兵，占一格
                    persons[i] = new Person(8,"小兵");
                    persons[i].setIcon(icons[8]);
                    persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, W);
                    break;
                case 9://小兵，占一格
                    persons[i] = new Person(9,"小兵");
                    persons[i].setIcon(icons[9]);
                    persons[i].setBounds(leftX+map[i].getY()*W, leftY+map[i].getX()*W, W, W);
                    break;
            }
            persons[i].addMouseListener(this);
            persons[i].addKeyListener(this);
            this.add(persons[i]);
        }
    }

    private String getDirection(){
        int dx,dy;
        String direction;
        dx = p2.x - p1.x;
        dy = p2.y - p1.y;
        if(dx==0&&dy==0){
            return "no move";
        }
        if(Math.abs(dx)>Math.abs(dy)){//水平方向的偏移大于竖直方向的偏移，即水平方向运动
            if(dx>0){//释放点在按压点右边
                direction =  "right";
            }else{
                direction =  "left";
            }

        }else{//竖直方向的偏移大于水平方向的偏移，即竖直方向运动
            if(dy>0){//释放点在按压点下边
                direction =  "down";
            }else{
                direction =  "up";
            }

        }
        return direction;
    }


    @Override
    public void mousePressed(MouseEvent e) {
        if(e.getSource()==null)//没有选中任何按钮，直接返回
            return ;
        p1.x = e.getX();
        p1.y = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if(e.getSource()==null)
            return ;
        Person man = (Person) e.getSource();
        p2.x = e.getX();
        p2.y = e.getY();
        String direction = getDirection();
        boolean canMoveFlag;
        if(direction.equals("up")){
            canMoveFlag = getCanMoveFlag(man,UP);
            if(canMoveFlag)
                move(man,UP);
        }else if(direction.equals("down")){
            canMoveFlag = getCanMoveFlag(man,DOWN);
            if(canMoveFlag)
                move(man,DOWN);
        }else if(direction.equals("left")){
            canMoveFlag = getCanMoveFlag(man,LEFT);
            if(canMoveFlag)
                move(man,LEFT);
        }else if(direction.equals("right")){
            canMoveFlag = getCanMoveFlag(man,RIGHT);
            if(canMoveFlag)
                move(man,RIGHT);
        }
    }



    private void move(Person man, int direction) {
        switch(direction){
            case UP:man.setLocation(man.getX(), man.getY()-W);break;
            case DOWN:man.setLocation(man.getX(), man.getY()+W);break;
            case LEFT:man.setLocation(man.getX()-W, man.getY());break;
            case RIGHT:man.setLocation(man.getX()+W, man.getY());break;
        }
        step++;
        GameClient.helpPanel.nowStep.setText(""+step);
        if(isWin(man)){
            if(level==10){JOptionPane.showMessageDialog(this, "恭喜通过最后一关");}
            else{
                String msg;
                if(step<mapUtil.getRecord(level)){
                    msg = "恭喜你通过第"+level+"关！！！\n通关步数是"+step+"\n刷新了历史记录"+mapUtil.getRecord(level)+"步\n是否要进入下一关？";
                    mapUtil.updateRecode(level, step);
                }else{
                    msg = "恭喜你通过第"+level+"关！！！\n通关步数是"+step+"\n"+"是否要进入下一关？";
                }
                int type = JOptionPane.YES_NO_OPTION;
                String title = "过关";
                int choice = 0;
                choice = JOptionPane.showConfirmDialog(null, msg,title,type);
                if(choice==1){
                    System.exit(0);
                }else if(choice == 0){
                    level++;
                    step = 0;
                    for(int i=0;i<10;i++){
                        this.remove(persons[i]);
                    }
                    repaint();
                    map = mapUtil.getMap(level);
                    GameClient.panel.remove(GameClient.helpPanel);
                    GameClient.helpPanel = new HelpPanel(level);
                    GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
                    GameClient.helpPanel.validate();
                    GameClient.gamePanel.validate();
                    GameClient.panel.validate();
                    initialize();
                    setVisible(true);
                    this.requestFocus();
                    HelpPanel.restart.removeMouseListener(this);
                    HelpPanel.restart.addMouseListener(new MouseAdapter(){
                        public void mouseClicked(MouseEvent e){
                            step = 0;
                            for(int i=0;i<10;i++){
                                GameClient.gamePanel.remove(persons[i]);
                            }
                            repaint();
                            map = mapUtil.getMap(level);
                            GameClient.panel.remove(GameClient.helpPanel);
                            GameClient.helpPanel = new HelpPanel(level);
                            GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
                            GameClient.helpPanel.validate();
                            GameClient.gamePanel.validate();
                            GameClient.panel.validate();
                            initialize();
                            setVisible(true);
                            GameClient.gamePanel.requestFocus();
                            repaint();
                        }
                    });
                }
            }
        }
    }


    private boolean isWin(Person man) {
        if(man.getId()==0&&man.getX()==leftX+W&&man.getY()==leftY+3*W){//如果移动的图块是曹操，并且曹操位于终点
            return true;
        }

        return false;
    }

    private boolean getCanMoveFlag(Person man, int direction) {

        boolean canMoveFlag = true;
        Rectangle manRect = man.getBounds();//返回点击的人物按钮对应的矩形对象
        int x = manRect.x;
        int y = manRect.y;
        if(direction ==UP){
            y -= W;
        }else if(direction == DOWN){
            y += W;
        }else if(direction == LEFT){
            x -= W;
        }else if(direction == RIGHT){
            x += W;
        }
        manRect.setLocation(x, y);//矩形进行了移动
        for(int i=0;i<10;i++){
            if(persons[i].getId()!=man.getId()){//位移后的矩形与其他人物图块对应的矩形进行碰撞检测
                Rectangle personRect = persons[i].getBounds();
                if(personRect.intersects(manRect)){//如果两矩形相交，说明不能移动
                    canMoveFlag = false;
                }
            }
        }

        //检测是否超出游戏区域
        if(manRect.intersects(upBoundary)||manRect.intersects(downBoundary)||manRect.intersects(leftBoundary)||manRect.intersects(rightBoundary)){
            canMoveFlag = false;
        }


        return canMoveFlag;
    }

    @Override
    public void keyPressed(KeyEvent e) {

        if(e.getKeyCode() == KeyEvent.VK_A){//上一关
            if(level==1){
                return;
            }
            level--;
            step = 0;
            for(int i=0;i<10;i++){
                GameClient.gamePanel.remove(persons[i]);
            }
            repaint();
            map = mapUtil.getMap(level);
            GameClient.panel.remove(GameClient.helpPanel);
            GameClient.helpPanel = new HelpPanel(level);
            GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
            GameClient.helpPanel.validate();
            GameClient.gamePanel.validate();
            GameClient.panel.validate();
            initialize();
            setVisible(true);
            GameClient.gamePanel.requestFocus();
            repaint();
            HelpPanel.restart.removeMouseListener(this);
            HelpPanel.restart.addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent e){
                    step = 0;
                    for(int i=0;i<10;i++){
                        GameClient.gamePanel.remove(persons[i]);
                    }
                    repaint();
                    map = mapUtil.getMap(level);
                    GameClient.panel.remove(GameClient.helpPanel);
                    GameClient.helpPanel = new HelpPanel(level);
                    GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
                    GameClient.helpPanel.validate();
                    GameClient.gamePanel.validate();
                    GameClient.panel.validate();
                    initialize();
                    setVisible(true);
                    GameClient.gamePanel.requestFocus();
                    repaint();
                }
            });
        }
        if(e.getKeyCode() == KeyEvent.VK_D){//下一关
            if(level==10){
                return;
            }
            level++;
            step = 0;
            for(int i=0;i<10;i++){
                GameClient.gamePanel.remove(persons[i]);
            }
            repaint();
            map = mapUtil.getMap(level);
            GameClient.panel.remove(GameClient.helpPanel);
            GameClient.helpPanel = new HelpPanel(level);
            GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
            GameClient.helpPanel.validate();
            GameClient.gamePanel.validate();
            GameClient.panel.validate();
            initialize();
            setVisible(true);
            GameClient.gamePanel.requestFocus();
            repaint();
            HelpPanel.restart.removeMouseListener(this);
            HelpPanel.restart.addMouseListener(new MouseAdapter(){
                public void mouseClicked(MouseEvent e){
                    step = 0;
                    for(int i=0;i<10;i++){
                        GameClient.gamePanel.remove(persons[i]);
                    }
                    repaint();
                    map = mapUtil.getMap(level);
                    GameClient.panel.remove(GameClient.helpPanel);
                    GameClient.helpPanel = new HelpPanel(level);
                    GameClient.panel.add(GameClient.helpPanel,BorderLayout.EAST);
                    GameClient.helpPanel.validate();
                    GameClient.gamePanel.validate();
                    GameClient.panel.validate();
                    initialize();
                    setVisible(true);
                    GameClient.gamePanel.requestFocus();
                    repaint();
                }
            });
        }

    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }

}
